<?php

/*
    Movie controller provides with functions which allow to view, add and edit movie information.
    Users can view movie information, but admins can add and edit this info.
*/

//Class used to manipulate with images.
require_once APPPATH.'\classes\custom\SimpleImage.php';

class Controller_Movie extends Controller_Template {
    private $user_data;
    private $user_id;
    private $language;
    
    //Time offset is used to adjust time-zone.
    private $time_offset = 10800;
    
    public function before() {
        $this->language = Cookie::get((Auth::check() ? 'user' : 'guest') . '_language', 'lv');
        Config::set("language", $this->language);
        Lang::load('main', null, $this->language, true);
        
        parent::before();
        $this->user_data = Auth::instance();
        $this->user_id = $this->user_data->get_user_id();
        
        $this->template->language = $this->language;
        $this->template->genres = Model_Orm_Genre::find('all');
        $this->template->cinema_info = Model_Orm_Cinema::find('first');
    }
    
    public function action_add() {
        if(!Auth::member(100)) {
            Response::redirect('/');
        }
        
        if(Input::method() == "POST") {
            $genres = array();
            
            //Gathering selected movie genres.
            for($movie_selection = 1; $movie_selection <= 3 && Input::post('Genre_' . $movie_selection) !== null; $movie_selection++) {                
                $genres[$movie_selection] = Input::post('Genre_' . $movie_selection);
            }
            
            if($this->has_duplicates($genres)) {
                Session::set_flash('error', 'Izvēlieties dažādus filmas žanrus !');
                Response::redirect('movie/add');
            } else {
                $validation = Model_Orm_Movie::validate('add');
                
                //Gets YouTube video ID from URL.
                $youtube_id = $this->get_video_id(Input::post('Trailer_Link'));
                
                if($validation->run() && Upload::is_valid() && $youtube_id !== null) {
                    
                    $upload_config = array(
                        'path' => DOCROOT.'uploads\\posters\\',
                        'ext_whitelist' => array('img', 'jpg', 'jpeg', 'gif', 'png'),
                    );     
                    
                    Upload::process($upload_config);
                    Upload::save();
                    $uploaded_file = Upload::get_files();
                    
                    //Getting the uploaded movie poster.
                    $img = new abeautifulsite\SimpleImage(DOCROOT.'uploads\posters\\'.$uploaded_file[0]["saved_as"]);
                    
                    //Converting the original uploaded image to two images with specific sizes.
                    $img->best_fit(200, 400)->save(DOCROOT.'uploads\posters\\poster_'.$uploaded_file[0]["saved_as"]);
                    $img->best_fit(60, 120)->save(DOCROOT.'uploads\posters\\small_'.$uploaded_file[0]["saved_as"]);
                    
                    //Deletes the original uploaded image as it will not be used.
                    @unlink(DOCROOT.'uploads\posters\\'.$uploaded_file[0]["saved_as"]);
                    
                    $new_movie = new Model_Orm_Movie();
                    $new_movie->title_lv = $validation->validated("Title_Lv");
                    $new_movie->title_en = $validation->validated("Title_En");
                    $new_movie->title_original = $validation->validated("Title_Original");
                    $new_movie->description_lv = $validation->validated("Description_Lv");
                    $new_movie->description_en = $validation->validated("Description_En");
                    $new_movie->age_restriction = $validation->validated("Age_Restriction");
                    $new_movie->year = $validation->validated("Year");
                    $new_movie->duration = $validation->validated("Duration");
                    $new_movie->video_id = $youtube_id;
                    $new_movie->poster_large = "poster_" . $uploaded_file[0]["saved_as"];
                    $new_movie->poster_small = "small_" . $uploaded_file[0]["saved_as"];
                    $new_movie->save();
                    
                    //Getting ID from the movie that was just added.
                    $newest_movie_id = Model_Orm_Movie::query()->max('id');
                    
                    //After movie is added, it is necessary to add movie genres.
                    foreach($genres as $genre_id) {
                        $new_movie_genre = new Model_Orm_Moviegenre();
                        $new_movie_genre->movie_id = $newest_movie_id;   
                        $new_movie_genre->genre_id = $genre_id; 
                        
                        $new_movie_genre->save();
                    }
                    
                    Session::set_flash('success', 'Filma veiksmīgi pievienota !');
                } else {
                    $upload_errors = Upload::get_errors();
                    Session::set_flash('error', $upload_errors);
                    Session::set_flash('error', $validation->error_message());
                }
            }
        }
        
        $genres = Model_Orm_Genre::load_genres();
        $custom_scripts = array('movies.js');
        $view_movie_add = View::forge('movie/add');
        $view_movie_add->set("genres", $genres);
        $this->template->page_custom_scripts = $custom_scripts;
        $this->template->page_content = $view_movie_add;
    }
    
    public function action_edit($movie_id = null) {
        if(!Auth::member(100)) {
            Response::redirect('/');
        }
        
        is_null($movie_id) and Response::redirect('/');       
        $movie_info = Model_Orm_Movie::find($movie_id);
        is_null($movie_info) and Response::redirect('/');
        
        if(Input::method() == "POST") {
            $genres = array();
            
            //Gathering selected movie genres.
            for($movie_selection = 1; $movie_selection <= 3 && Input::post('Genre_' . $movie_selection) !== null; $movie_selection++) {                
                $genres[$movie_selection] = Input::post('Genre_' . $movie_selection);
            }
            
            //If there are duplicated among selected genres, show error.
            if($this->has_duplicates($genres)) {
                Session::set_flash("error", "Izvēlieties dažādus žanrus !");
                Response::redirect('movie/edit/'.$movie_id);
            } else {
                $validation = Model_Orm_Movie::validate('add');
                $youtube_id = $this->get_video_id(Input::post('Trailer_Link'));
                
                if($validation->run() && Upload::is_valid() && $youtube_id !== null) {
                    
                    //Deleting previous movie info (genres) from the DB, as well as old images.
                    $old_genres = Model_Orm_Moviegenre::query()->where('movie_id', '=', $movie_id)->get();
                    foreach($old_genres as $genre) {
                        $genre->delete();
                    }
                     
                    @unlink(DOCROOT.'uploads\posters\\' . $movie_info->poster_large);
                    @unlink(DOCROOT.'uploads\posters\\' . $movie_info->poster_small);
                    
                    $upload_config = array(
                        'path' => DOCROOT.'uploads\\posters\\',
                        'ext_whitelist' => array('img', 'jpg', 'jpeg', 'gif', 'png'),
                    );     
                    
                    Upload::process($upload_config);
                    Upload::save();
                    $uploaded_file = Upload::get_files();
                    
                    //New movie poster image; deletes the old poster images.
                    $img = new abeautifulsite\SimpleImage(DOCROOT.'uploads\posters\\'.$uploaded_file[0]["saved_as"]);
                    $img->best_fit(200, 400)->save(DOCROOT.'uploads\posters\\poster_'.$uploaded_file[0]["saved_as"]);
                    $img->best_fit(60, 120)->save(DOCROOT.'uploads\posters\\small_'.$uploaded_file[0]["saved_as"]);
                    @unlink(DOCROOT.'uploads\posters\\'.$uploaded_file[0]["saved_as"]);
                    
                    $movie = Model_Orm_Movie::find($movie_id);
                    $movie->title_lv = $validation->validated("Title_Lv");
                    $movie->title_en = $validation->validated("Title_En");
                    $movie->title_original = $validation->validated("Title_Original");
                    $movie->description_lv = $validation->validated("Description_Lv");
                    $movie->description_en = $validation->validated("Description_En");
                    $movie->age_restriction = $validation->validated("Age_Restriction");
                    $movie->year = $validation->validated("Year");
                    $movie->duration = $validation->validated("Duration");
                    $movie->video_id = $youtube_id;
                    $movie->poster_large = "poster_" . $uploaded_file[0]["saved_as"];
                    $movie->poster_small = "small_" . $uploaded_file[0]["saved_as"];
                    $movie->save();
                   
                    //Adds movie genres to the movie.
                    foreach($genres as $genre_id) {
                        $new_movie_genre = new Model_Orm_Moviegenre();
                        $new_movie_genre->movie_id = $movie_id;   
                        $new_movie_genre->genre_id = $genre_id; 
                        
                        $new_movie_genre->save();
                    }
                } else {
                    Session::set_flash('error', $validation->error_message());
                    Response::redirect('movie/edit/'.$movie_id);
                }
            }
        }
        
        $genres = Model_Orm_Genre::load_genres();
        $custom_scripts = array('movies.js');
        $view_movie_add = View::forge('movie/edit');
        $view_movie_add->set("genres", $genres);
        $view_movie_add->set("movie_info", $movie_info);
        $this->template->page_custom_scripts = $custom_scripts;
        $this->template->page_content = $view_movie_add;
    }
    
    public function action_view($movie_id = null) {
        is_null($movie_id) and Response::redirect('/');
        
        $movie_info = Model_Orm_Movie::find($movie_id);
        
        is_null($movie_info) and Response::redirect('/');
        
        //Getting all movie reviews.
        $reviews = $movie_info->get('reviews');
        
        $shows = Model_Orm_Show::query()->where('movie_id', '=', $movie_id)->where('start_time', '>', time() + $this->time_offset)->order_by('start_time', 'asc')->limit(3)->get();
        $genres = $movie_info->get('genres');
        
        //Assigning usernames to movie reviews.
        foreach($reviews as $review) {
            $user_data = Model_Orm_User::find('first', array('where' => array(array('id', $review->user_id))));
            $review->username = $user_data['username'];
        }
        
        $view_movie_view = View::forge('movie/view');
        $view_movie_view->set("movie_info", $movie_info);
        $view_movie_view->set("reviews", $reviews);
        $view_movie_view->set("shows", $shows);
        $view_movie_view->set("genres", $genres);
        $view_movie_view->set("language", $this->language);
        $this->template->page_content = $view_movie_view;    
    }
    
    //Adds new movie review.
    public function action_newreview() {
        if(Input::method() == 'POST') {
            $validation = Model_Orm_Review::validate('add');
            
            if($validation->run()) {
                $new_review = new Model_Orm_Review();
                
                $new_review->movie_id = $validation->validated("Movie_ID");
                $new_review->user_id = $this->user_id[1];
                
                //Save rating only if used has selected rating > 0.
                if($validation->validated("Rating") > 0) {
                    $new_review->rating = $validation->validated("Rating");
                }
                
                $new_review->review = $validation->validated("Review");
                $new_review->date = time()+$this->time_offset;
                
                $new_review->save();
            }
            
            Response::redirect('movie/view/' . Input::post('Movie_ID') );
        }
        
        Response::redirect('/');
    }
    
    //Image convertion
    public function action_imgconvert() {
        if (Input::method() == "POST" && Upload::is_valid()) {
            $upload_config = array(
                'path' => DOCROOT.'uploads\\convert\\',
                'ext_whitelist' => array('img', 'jpg', 'jpeg', 'gif', 'png'),
            );     

            Upload::process($upload_config);
            Upload::save();
            $uploaded_file = Upload::get_files();
            
            $img = new abeautifulsite\SimpleImage(DOCROOT.'uploads\convert\\'.$uploaded_file[0]["saved_as"]);
            $img->best_fit(60, 120)->save(DOCROOT.'uploads\convert\\small_'.$uploaded_file[0]["saved_as"]);
            unlink(DOCROOT.'uploads\convert\\'.$uploaded_file[0]["saved_as"]);
        }
        
        $view_convert = View::forge('movie/convert');
        $this->template->page_content = $view_convert;  
    }
    
    //Checks if an array holds duplicate values.
    public function has_duplicates($array) {
        return count($array) !== count(array_unique($array));
    }
    
    //Gets YouTube video ID from URL.
    public function get_video_id($url) {
        preg_match("#(?<=v=)[a-zA-Z0-9-]+(?=&)|(?<=v\/)[^&\n]+(?=\?)|(?<=v=)[^&\n]+|(?<=youtu.be/)[^&\n]+#", $url, $matches);
        
        if(count($matches) > 0) {
            return $matches[0];
        }
        
        return null;
    }
}

?>
